﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Microsoft.Samples.DslTools.ConfigurationSectionDesigner
{
    public abstract partial class BaseConfigurationType
    {
        #region Convenience Properties

        /// <summary>
        /// Gets the value of the calculated TypeName property.
        /// </summary>
        /// <remarks>
        /// This property is used to show the actual type of the MEL in the shape,
        /// i.e. ConfigurationElement, ConfigurationElementCollection or ConfigurationSection.
        /// </remarks>
        public string GetTypeNameValue()
        {
            return this.GetType().Name;
        }

        /// <summary>
        /// Gets the full type name of this configuration type.
        /// </summary>
        public string FullName
        {
            get
            {
                return string.Format( "{0}.{1}", this.ActualNamespace, this.Name );
            }
        }

        /// <summary>
        /// Gets the actual namespace this configuration type should be declared in.
        /// </summary>
        public string ActualNamespace
        {
            get
            {
                return string.IsNullOrEmpty( this.Namespace ) ? this.ConfigurationSectionModel.Namespace : this.Namespace;
            }
        }

        #endregion

        #region NameChanged Event (for validation and for derived classes to set XML name)

        /// <summary>
        /// Occurs when the name of the ConfigurationElement changed.
        /// </summary>
        protected event EventHandler<EventArgs> NameChanged;

        /// <summary>
        /// Raises the <see cref="E:NameChanged"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected virtual void OnNameChanged( EventArgs e )
        {
            if( this.NameChanged != null )
            {
                this.NameChanged( this, EventArgs.Empty );
            }
        }

        internal sealed partial class NamePropertyHandler
        {
            protected override void OnValueChanged( BaseConfigurationType element, string oldValue, string newValue )
            {
                if( !element.Store.InUndoRedoOrRollback )
                {
                    // Hard validation of the new name.
                    if( string.IsNullOrEmpty( newValue ) )
                    {
                        throw new ArgumentException( "The Name is required and cannot be an empty string.", newValue );
                    }

                    // Raise the NameChanged event for derived classes to act upon.
                    element.OnNameChanged( EventArgs.Empty );
                }

                // Always call the base class method.
                base.OnValueChanged( element, oldValue, newValue );
            }
        }

        #endregion
    }
}
